package net.lbh.baidumap;

import android.content.Context;
import android.graphics.Point;
import android.util.Log;
import android.view.View;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;
import com.baidu.mapapi.map.BaiduMap;
import com.baidu.mapapi.map.BaiduMap.OnMapClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMapStatusChangeListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerClickListener;
import com.baidu.mapapi.map.BaiduMap.OnMarkerDragListener;
import com.baidu.mapapi.map.BitmapDescriptor;
import com.baidu.mapapi.map.BitmapDescriptorFactory;
import com.baidu.mapapi.map.MapStatus;
import com.baidu.mapapi.map.MapStatusUpdate;
import com.baidu.mapapi.map.MapStatusUpdateFactory;
import com.baidu.mapapi.map.MapView;
import com.baidu.mapapi.map.MarkerOptions;
import com.baidu.mapapi.map.MyLocationConfiguration;
import com.baidu.mapapi.map.MyLocationData;
import com.baidu.mapapi.map.Overlay;
import com.baidu.mapapi.map.OverlayOptions;
import com.baidu.mapapi.map.UiSettings;
import com.baidu.mapapi.map.MyLocationConfiguration.LocationMode;
import com.baidu.mapapi.model.LatLng;
import com.baidu.mapapi.search.geocode.GeoCodeOption;
import com.baidu.mapapi.search.geocode.GeoCoder;
import com.baidu.mapapi.search.geocode.OnGetGeoCoderResultListener;
import com.baidu.mapapi.search.geocode.ReverseGeoCodeOption;
import com.baidu.mapapi.search.poi.PoiSearch;
import com.baidu.mapapi.search.route.DrivingRoutePlanOption;
import com.baidu.mapapi.search.route.OnGetRoutePlanResultListener;
import com.baidu.mapapi.search.route.PlanNode;
import com.baidu.mapapi.search.route.RoutePlanSearch;
import com.baidu.mapapi.search.route.TransitRoutePlanOption;
import com.baidu.mapapi.search.route.WalkingRoutePlanOption;
import com.baidu.mapapi.utils.CoordinateConverter;
import com.baidu.mapapi.utils.DistanceUtil;

public class BaiduMapAgent {

	private static final String TAG = BaiduMapAgent.class.getName();

	private MapView mMapView;
	private BaiduMap mBaiduMap;
	private UiSettings mUiSettings;

	private PoiSearch mPoiDetailSearch;

	private LocationClient mLocClient;
	private BDLocationListener mBdLocationListener;
	private boolean isLocationing;

	/** 物理地址编码/解码 ，反向编码 */
	private GeoCoder mGeoCoder;
	/** 地址 编解码 监听器 */
	private OnGetGeoCoderResultListener mOnGetGeoCoderResultListener;

	/** 路线规划 */
	private RoutePlanSearch mRoutePlanSearch;
	/** 路线规划 监听器 */
	private OnGetRoutePlanResultListener mOnGetRoutePlanResultListener;

	private Context mContext;
	private Context mAppContext;

	private boolean isDestroied;

	private static float mZoomTo = 17.0f;

	public static final double pi = 3.1415926535897932384626;

	public interface CoordType {
		/** bd09 == BD09_MC */
		public static final String BD09_MC = "bd09";
		public static final String BD09LL = "bd09ll";
		public static final String GCJ02 = "gcj02";
	}

	public BaiduMapAgent(Context context) {
		this.mContext = context;
		this.mAppContext = context.getApplicationContext();
	}

	public static BaiduMapAgent newInstance(MapView mapViwe) {
		return new BaiduMapAgent(mapViwe);
	}

	public static BaiduMapAgent newInstance(Context context) {
		return new BaiduMapAgent(context);
	}

	public BaiduMapAgent(MapView mapViwe) {
		this.mMapView = mapViwe;
		configContext();
	}

	public void setMapView(MapView mapView) {
		this.mMapView = mapView;
		configContext();
	}

	public void onResume() {
		if (mMapView != null) {
			mMapView.setVisibility(View.VISIBLE);
			mMapView.onResume();
		}
	}

	public void onPause() {
		if (mMapView != null) {
//			mMapView.setVisibility(View.INVISIBLE);
			if (mBaiduMap!=null) {
				mBaiduMap.setMyLocationEnabled(true);
			}
			mMapView.onPause();
		}
	}

	/**
	 * 
	 * 销毁 百度地图
	 * 
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午6:55:13
	 * @update (date)
	 */
	public void onDestroy() {

		isDestroied = true;
		// 退出时销毁POI详情搜索
		if (mPoiDetailSearch != null) {
			mPoiDetailSearch.destroy();
			mPoiDetailSearch = null;
		}

		// 关闭定位
		if (null != mLocClient) {
			if (mBdLocationListener !=null) {
				unRegisterLocationListener(mBdLocationListener);
			}
			mLocClient.stop();
			mLocClient= null;
			isLocationing = false;
		}

		if (null != mGeoCoder) {
			mGeoCoder.destroy();
			mGeoCoder = null;
		}

		// 关闭定位图层
		if (this.mBaiduMap != null) {
			this.mBaiduMap.setMyLocationEnabled(false);
			this.mBaiduMap.clear();
			this.mBaiduMap = null;
		}

		if (this.mMapView != null) {
			this.mMapView.onDestroy();
			this.mMapView = null;
		}

	}

	private void configContext() {
		if (null == this.mMapView) {
			throw new IllegalArgumentException(
					" mapview is null ,please call setMapView() method!");
		}
		this.mContext = this.mMapView.getContext();
		this.mAppContext = this.mMapView.getContext().getApplicationContext();
		configBaiduMap();
		configBaidumapUiSettings();
	}

	private void configBaiduMap() {
		this.mBaiduMap = this.mMapView.getMap();
	}

	private void configBaidumapUiSettings() {
		mUiSettings = mBaiduMap.getUiSettings();
	}

	public boolean isDestroy() {
		return isDestroied;
	}

	// ///////////////////////////////////////////////get
	// method/////////////////////////////////////////////////////
	public BaiduMap getBaiduMap() {
		return this.mBaiduMap;
	}

	public UiSettings getBaiduMapUiSettings() {
		return this.mUiSettings;
	}
	
	public LocationClient getLocationClient(){
		return this.mLocClient;
	}
	
	/**
	 *
	 * 获取 MapView 中心点的 经纬度
	* @return LatLng
	* @autour BaoHong.Li
	* @date 2015-8-17 上午10:06:25 
	* @update (date)
	 */
	
	public LatLng getMapCenterLocation(){
//		getMapCenterLocation(this.mBaiduMap.getMapStatus());
		return this.mBaiduMap.getMapStatus().target;
	}
	
	public LatLng getMapCenterLocation(MapStatus mapStatus){
		return this.mBaiduMap.getProjection().fromScreenLocation(new Point(mapStatus.targetScreen.x,mapStatus.targetScreen.y));
	}

	/**
	 * 返回两个点之间的距离
	 * 
	 * @param p1LL
	 *            起点的百度经纬度坐标
	 * @param p2LL
	 *            :终点的百度经纬度坐标
	 * @return double (两点距离，单位为： 米,转换错误时返回-1)
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:23:58
	 * @update (date)
	 */
	public static double getDistance(LatLng p1LL, LatLng p2LL) {
		return DistanceUtil.getDistance(p1LL, p2LL);
	}

	// ///////////////////////////////////////////////set
	// method/////////////////////////////////////////////////////

	public void setRotateGesturesEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setRotateGesturesEnabled(enable);
	}

	public void setCompassEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setCompassEnabled(enable);
	}

	public void setOverlookingGesturesEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setOverlookingGesturesEnabled(enable);
	}

	public void setAllGesturesEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setAllGesturesEnabled(enable);
	}

	public void setScrollGesturesEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setScrollGesturesEnabled(enable);
	}

	public void setZoomGesturesEnabled(boolean enable) {
		if (this.mUiSettings == null) {
			return;
		}
		mUiSettings.setZoomGesturesEnabled(enable);
	}

	public void setMyLocationConfigeration(MyLocationConfiguration configuration) {
		if (this.mBaiduMap == null) {
			return;
		}
		this.mBaiduMap.setMyLocationConfigeration(configuration);
	}

	public void setLocationMode(LocationMode mode) {
		setMyLocationConfigeration(new MyLocationConfiguration(mode, true, null));
	}

	/**
	 * 
	 * @param type
	 *            [BaiduMap.MAP_TYPE_NORMAL(普通地图)
	 *            \BaiduMap.MAP_TYPE_SATELLITE（卫星地图） ]
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:56:11
	 * @update (date)
	 */
	public void setMapType(int type) {
		if (this.mBaiduMap == null) {
			return;
		}
		mBaiduMap.setMapType(type);
	}

	/**
	 *  设置 mapview 缩放 比例，zoomTo 为0 ，为默认maxZoomLeavel - 3f
	* @return void
	* @autour BaoHong.Li
	* @date 2015-8-14 下午5:21:42 
	* @update (date)
	 */
	public void setMapViewZoomTo() {
		setMapViewZoomTo(0);
	}
	
	/**
	 * 
	 * 设置 mapview 缩放 比例，zoomTo 为0 ，为默认 17.0f
	 * 
	 * @param zoomTo
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:50:26
	 * @update (date)
	 */
	public void setMapViewZoomTo(float zoomTo) {
		if (this.mBaiduMap == null) {
			return;
		}
		if (zoomTo != 0) {
			mZoomTo = zoomTo;
		}
		mZoomTo = this.mBaiduMap.getMaxZoomLevel() -3f;
		MapStatusUpdate u2 = MapStatusUpdateFactory.zoomTo(mZoomTo);
		this.mBaiduMap.setMapStatus(u2);
//		this.mBaiduMap.animateMapStatus(u2);
	}

	public void setMyLocationData(MyLocationData locData) {
		if (this.mBaiduMap!=null) {
			this.mBaiduMap.setMyLocationData(locData);
		}
	}

	/**
	 * 
	 * Custom setMyLocationData
	 * 
	 * @param location
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 上午10:13:27
	 * @update (date)
	 */
	public void setMyLocationData(BDLocation location) {
		if (this.mBaiduMap == null) {
			return;
		}
		MyLocationData locData = new MyLocationData.Builder()
				.accuracy(location.getRadius())
				// 此处设置开发者获取到的方向信息，顺时针0-360
				.direction(100).latitude(location.getLatitude())
				.longitude(location.getLongitude()).build();
		this.mBaiduMap.setMyLocationData(locData);
	}
	
	/**
	 *
	 * 打开定位图层 
	* @param enable
	* @return void
	* @autour Lbh
	* @date 2015-8-22 下午10:24:40 
	* @update (date)
	 */
	public void setMyLocationEnabled(boolean enable){
		if (this.mBaiduMap == null) {
			return;
		}
		this.mBaiduMap.setMyLocationEnabled(enable);
	}

	/**
	 * 
	 * 开启 时时交通图
	 * 
	 * @param isTraffic
	 *            [true / false ,开启，关闭]
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:57:18
	 * @update (date)
	 */
	public void setTrafficEnabled(boolean isTraffic) {
		if (this.mBaiduMap == null) {
			return;
		}
		this.mBaiduMap.setTrafficEnabled(isTraffic);
	}

	/**
	 * 开启 城市 城市热力图
	 * 
	 * @param isHeatMap
	 *            [true / false ,开启，关闭]
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:58:49
	 * @update (date)
	 */
	public void setBaiduHeatMapEnabled(boolean isHeatMap) {
		if (this.mBaiduMap == null) {
			return;
		}
		this.mBaiduMap.setBaiduHeatMapEnabled(isHeatMap);
	}

	/**
	 * 
	 * 地图点击事件 ---> 可以获取对应的地理坐标
	 * 
	 * @param listener
	 *            >
	 *            <p>
	 *            onMapPoiClick[ //在此处理点击事件 ]
	 *            <p>
	 *            onMapPoiClick [//在此处理底图标注点击事件 ]
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:29:46
	 * @update (date)
	 */
	public void setOnMapViewClick(OnMapClickListener listener) {
		if (this.mBaiduMap == null) {
			return;
		}
		mBaiduMap.setOnMapClickListener(listener);
	}

	public void setOnMarkerClickListener(OnMarkerClickListener listenner) {
		if (this.mBaiduMap == null) {
			return;
		}
		mBaiduMap.setOnMarkerClickListener(listenner);
	}

	public void setOnMapStatusChangeListener(OnMapStatusChangeListener listenner) {
		if (this.mBaiduMap == null) {
			return;
		}
		mBaiduMap.setOnMapStatusChangeListener(listenner);
	}

	/**
	 * 
	 * 调用BaiduMap对象的setOnMarkerDragListener方法设置marker拖拽的监听
	 * 
	 * @param listener
	 *            [onMarkerDrag //拖拽中]
	 *            <p>
	 *            onMarkerDragEnd //拖拽结束
	 *            <p>
	 *            onMarkerDragStart //开始拖拽
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午8:16:18
	 * @update (date)
	 */
	public void setOnMarkerDragListener(OnMarkerDragListener listener) {
		if (this.mBaiduMap == null) {
			return;
		}
		mBaiduMap.setOnMarkerDragListener(listener);
	}

	// /////////////////////////////////logic//
	// method/////////////////////////////////////////////////////////////////

	/**
	 * 
	 * 设置是否显示缩放控件
	 * 
	 * @param show
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:08:36
	 * @update (date)
	 */
	public void showZoomControls(boolean show) {
		if (this.mBaiduMap == null) {
			return;
		}
		mMapView.showZoomControls(show);
	}

	/**
	 * 
	 * 设置是否显示比例尺控件
	 * 
	 * @param show
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:08:44
	 * @update (date)
	 */
	public void showScaleControl(boolean show) {
		if (this.mBaiduMap == null) {
			return;
		}
		mMapView.showScaleControl(show);
	}

	/**
	 * 
	* @param scanSpan 定位 时间，0为 指只为一次
	* @param listenner
	* @return void
	* @autour Lbh
	* @date 2015-9-5 下午6:35:55 
	* @update (date)
	 */
	public void startLocation(int scanSpan,BDLocationListener listenner) {
		startLocation(CoordType.BD09LL,scanSpan, listenner);
	}

	/**
	 * 
	 * 常用 定位方法 使用默认的 bd09ll 坐标系 ,默认 1000ms定位一次 
	 * 
	 * @param listenner
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午7:14:19
	 * @update (date)
	 */
	public void startLocation(BDLocationListener listenner) {
		startLocation(CoordType.BD09LL,1000, listenner);
	}

	/**
	 * 
	 * @param coorType
	 *            坐标类型 分别是bd09, bd09ll和gcj02
	 * @param listenner
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午3:50:06
	 * @update (date)
	 */
	public void startLocation(String coorType,int scanSpan, BDLocationListener listenner) {
		mLocClient = new LocationClient(this.mAppContext);
		mBdLocationListener = listenner;
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);// 打开gps
		option.setCoorType(coorType); // 设置坐标类型
		option.setScanSpan(scanSpan);
		option.setIsNeedAddress(true); ////可选，设置是否需要地址信息
		option.setIsNeedLocationPoiList(true);//可选，默认false，设置是否需要POI结果，可以在BDLocation.getPoiList里得到
		mLocClient.setLocOption(option);
		startLocation(mBdLocationListener, mLocClient);
	}

	public void startLocation(BDLocationListener listenner,
			LocationClient mLocClient) {
		
		if (this.mBaiduMap!=null) {
			
			// 开启定位图层
			mBaiduMap.setMyLocationEnabled(true);
			// 设置方向
			mBaiduMap.setMyLocationConfigeration(new MyLocationConfiguration(
					LocationMode.NORMAL, true, null));
		}
		// 开始定位
		mLocClient.registerLocationListener(listenner);
		mLocClient.start();
		mLocClient.requestLocation();
		isLocationing = true;
	}
	

	/**
	 * 
	 * 当 启用了 定位 后，（startlocatino）
	 * 
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-13 上午10:58:33
	 * @update (date)
	 */
	public void requestLocation() {
		if (!isLocationing && mLocClient != null) {
			mLocClient.requestLocation();
		} else
			Log.w(TAG, "request fail , please call startLocation method!");
	}

	public void unRegisterLocationListener(BDLocationListener listenner) {
		if (null != mLocClient) {
			mLocClient.unRegisterLocationListener(listenner);
		}

	}
	
	/**
	 *
	 * 停止定位
	* @return void
	* @autour Lbh
	* @date 2015-9-5 下午6:31:11 
	* @update (date)
	 */
	public void stopLocation(){
		if (mLocClient !=null) {
			mLocClient.stop();
			mLocClient = null;
		}else {
			Log.w(TAG, " location is not start!");
		}
	}
	
	public void movePositionToCenter(BDLocation location) {
		movePositionToCenter(location.getLatitude(), location.getLongitude());
	}

	/**
	 *
	 * 移动改 坐标到mapview的中心点，并且 缩放地图到默认比例
	* @param location
	* @return void
	* @autour BaoHong.Li
	* @date 2015-8-14 下午5:39:25 
	* @update (date)
	 */
	public void movePositionAndZoomToCenter(BDLocation location) {
		movePositionToCenter(location.getLatitude(), location.getLongitude());
		setMapViewZoomTo();
	}
	
	

	/**
	 * 
	 * 移动 mapView 上的 该点 到地图中心
	 * 
	 * @param latitude
	 * @param longitude
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午8:39:38
	 * @update (date)
	 */
	public void movePositionToCenter(double latitude, double longitude) {
		movePositionToCenter(new LatLng(latitude, longitude));
	}

	/**
	 * 移动 mapView 上的 该点 到地图中心
	 * 
	 * @param location
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午8:40:05
	 * @update (date)
	 */
	public void movePositionToCenter(LatLng location) {
		MapStatusUpdate u = MapStatusUpdateFactory.newLatLng(location);
		mBaiduMap.animateMapStatus(u);
	}

	public Overlay addMarker(double latitude, double longitude,
			int markerIconResId) {
		return addMarker(new LatLng(latitude, longitude), markerIconResId);
	}

	public Overlay addMarker(LatLng location, int markerIconResId) {
		// 构建Marker图标
		BitmapDescriptor bitmap = null;
		if (markerIconResId != 0) {
			bitmap = BitmapDescriptorFactory.fromResource(markerIconResId);
		}
		// 构建MarkerOption，用于在地图上添加Marker
		MarkerOptions options = new MarkerOptions();
		options.position(location);
		if (bitmap != null) {
			options.icon(bitmap);
		}
		// 在地图上添加Marker，并显示
		return addMarker(options);
	}

	/**
	 * 
	 * 在地图上添加Marker，并显示
	 * 
	 * @param options
	 * @return Overlay
	 * @autour BaoHong.Li
	 * @date 2015-8-11 下午8:00:43
	 * @update (date)
	 */
	public Overlay addMarker(OverlayOptions options) {
		if (mBaiduMap != null && options != null) {
			return mBaiduMap.addOverlay(options);
		}
		return null;
	}

	/**
	 * 
	 * 移除 地图上 所有 marker
	 * 
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午2:04:42
	 * @update (date)
	 */
	public void clearAllMarkers() {
		if (mBaiduMap != null) {
			mBaiduMap.clear();
		}
	}

	/**
	 * 将地理 地址编码成 百度经纬度【地址 -> 经纬度 】
	 * 
	 * @param city
	 *            城市
	 * @param address
	 *            地址
	 * @param listener
	 *            [ onGetReverseGeoCodeResult :经纬度 -> 地址]
	 *            <p>
	 *            [onGetGeoCodeResult :地址 -> 经纬度]
	 *            <p>
	 * @return void
	 * @throws
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午3:26:32
	 * @update (date)
	 */
	public void enCode(String city, String address,
			OnGetGeoCoderResultListener listener) {
		GeoCodeOption geoCodeOption = new GeoCodeOption();
		geoCodeOption.city(city);
		geoCodeOption.address(address);
		enCode(geoCodeOption, listener);
	}

	/**
	 * 
	 * 将地理 地址编码成 百度经纬度 【 地址-> 经纬度】
	 * 
	 * @param listener
	 *            [ onGetReverseGeoCodeResult :经纬度 -> 地址]
	 *            <p>
	 *            [onGetGeoCodeResult :地址 -> 经纬度]
	 *            <p>
	 * @param option
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午3:07:31
	 * @update (date)
	 */
	public void enCode(GeoCodeOption option,
			OnGetGeoCoderResultListener listener) {
		if (mGeoCoder == null) {
			mGeoCoder = GeoCoder.newInstance();
		}
		if (listener == null) {
			throw new IllegalArgumentException(
					"OnGetGeoCoderResultListener is null");
		}
		mOnGetGeoCoderResultListener = listener;
		mGeoCoder.geocode(option);
		mGeoCoder.setOnGetGeoCodeResultListener(mOnGetGeoCoderResultListener);
	}

	/**
	 * 将经纬度 搜索对应的 地理 地址 【经纬度 -> 地址 】
	 * 
	 * @param latitude
	 *            经度
	 * @param longitude
	 *            维度
	 * @param listener
	 *            [ onGetReverseGeoCodeResult :经纬度 -> 地址]
	 *            <p>
	 *            [onGetGeoCodeResult :地址 -> 经纬度]
	 *            <p>
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午3:16:10
	 * @update (date)
	 */
	public void deCode(double latitude, double longitude,
			OnGetGeoCoderResultListener listener) {
		LatLng latLng = new LatLng(latitude, longitude);
		deCode(new ReverseGeoCodeOption().location(latLng), listener);
	}

	/**
	 * 将经纬度 搜索对应的 地理 地址 【经纬度 -> 地址 】
	 * 
	 * @param location
	 *            地标 【 经纬度】
	 * @param listener
	 *            [ onGetReverseGeoCodeResult :经纬度 -> 地址]
	 *            <p>
	 *            [ onGetGeoCodeResult :地址 -> 经纬度]
	 *            <p>
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午3:20:15
	 * @update (date)
	 */
	public void deCode(LatLng location, OnGetGeoCoderResultListener listener) {
		deCode(new ReverseGeoCodeOption().location(location), listener);
	}

	public void deCode(ReverseGeoCodeOption option,
			OnGetGeoCoderResultListener listener) {
		if (mGeoCoder == null) {
			mGeoCoder = GeoCoder.newInstance();
		}
		if (listener == null) {
			throw new IllegalArgumentException(
					"OnGetGeoCoderResultListener is null");
		}
		mOnGetGeoCoderResultListener = listener;
		mGeoCoder.reverseGeoCode(option);
		mGeoCoder.setOnGetGeoCodeResultListener(mOnGetGeoCoderResultListener);
	}

	/**
	 * 驾车 路线规划
	 * 
	 * @param fromCity
	 *            起点 城市
	 * @param fromPlace
	 *            起点 地址
	 * @param toCity
	 *            终点 城市
	 * @param toPlace
	 *            终点 地址
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:24:18
	 * @update (date)
	 */
	public void startDrivingRoutePlan(String fromCity, String fromPlace,
			String toCity, String toPlace, OnGetRoutePlanResultListener listener) {
		startDrivingRoutePlan(
				PlanNode.withCityNameAndPlaceName(fromCity, fromPlace),
				PlanNode.withCityNameAndPlaceName(toCity, toPlace), listener);
	}

	/**
	 * 
	 * 驾车 路线规划
	 * 
	 * @param fromPos
	 *            起点 坐标（经纬度）
	 * @param toPos
	 *            终点 坐标（经纬度）
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:25:01
	 * @update (date)
	 */
	public void startDrivingRoutePlan(LatLng fromPos, LatLng toPos,
			OnGetRoutePlanResultListener listener) {
		startDrivingRoutePlan(PlanNode.withLocation(fromPos),
				PlanNode.withLocation(toPos), listener);
	}

	public void startDrivingRoutePlan(PlanNode fromNode, PlanNode toNode,
			OnGetRoutePlanResultListener listener) {
		DrivingRoutePlanOption drivingRoutePlanOption = new DrivingRoutePlanOption();
		drivingRoutePlanOption.from(fromNode);
		drivingRoutePlanOption.to(toNode);
		startDrivingRoutePlan(drivingRoutePlanOption, listener);
	}

	public void startDrivingRoutePlan(DrivingRoutePlanOption option,
			OnGetRoutePlanResultListener listener) {
		if (null == mRoutePlanSearch) {
			mRoutePlanSearch = RoutePlanSearch.newInstance();
		}

		if (listener == null) {
			throw new IllegalArgumentException(
					"OnGetRoutePlanResultListener is null");
		}
		mOnGetRoutePlanResultListener = listener;
		mRoutePlanSearch
				.setOnGetRoutePlanResultListener(mOnGetRoutePlanResultListener);

		mRoutePlanSearch.drivingSearch(option);
	}

	/**
	 * 公交 路线规划
	 * 
	 * @param fromCity
	 *            起点 城市
	 * @param fromPlace
	 *            起点 地址
	 * @param toCity
	 *            终点 城市
	 * @param toPlace
	 *            终点 地址
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:32:40
	 * @update (date)
	 */
	public void startTransitRoutePlan(String fromCity, String fromPlace,
			String toCity, String toPlace, OnGetRoutePlanResultListener listener) {
		startTransitRoutePlan(
				PlanNode.withCityNameAndPlaceName(fromCity, fromPlace),
				PlanNode.withCityNameAndPlaceName(toCity, toPlace), listener);
	}

	/**
	 * 公交 路线规划
	 * 
	 * @param fromPos
	 *            起点 坐标（经纬度）
	 * @param toPos
	 *            终点 坐标（经纬度）
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:25:01
	 * @update (date)
	 */
	public void startTransitRoutePlan(LatLng fromPos, LatLng toPos,
			OnGetRoutePlanResultListener listener) {
		startTransitRoutePlan(PlanNode.withLocation(fromPos),
				PlanNode.withLocation(toPos), listener);
	}

	public void startTransitRoutePlan(PlanNode fromNode, PlanNode toNode,
			OnGetRoutePlanResultListener listener) {
		TransitRoutePlanOption transitRoutePlanOption = new TransitRoutePlanOption();
		transitRoutePlanOption.from(fromNode);
		transitRoutePlanOption.to(toNode);
		startTransitRoutePlan(transitRoutePlanOption, listener);
	}

	public void startTransitRoutePlan(TransitRoutePlanOption option,
			OnGetRoutePlanResultListener listener) {
		if (null == mRoutePlanSearch) {
			mRoutePlanSearch = RoutePlanSearch.newInstance();
		}

		if (listener == null) {
			throw new IllegalArgumentException(
					"OnGetRoutePlanResultListener is null");
		}
		mOnGetRoutePlanResultListener = listener;
		mRoutePlanSearch
				.setOnGetRoutePlanResultListener(mOnGetRoutePlanResultListener);

		mRoutePlanSearch.transitSearch(option);
	}

	/**
	 * 步行 路线规划
	 * 
	 * @param fromCity
	 *            起点 城市
	 * @param fromPlace
	 *            起点 地址
	 * @param toCity
	 *            终点 城市
	 * @param toPlace
	 *            终点 地址
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:32:40
	 * @update (date)
	 */
	public void startWalkingRoutePlan(String fromCity, String fromPlace,
			String toCity, String toPlace, OnGetRoutePlanResultListener listener) {
		startTransitRoutePlan(
				PlanNode.withCityNameAndPlaceName(fromCity, fromPlace),
				PlanNode.withCityNameAndPlaceName(toCity, toPlace), listener);
	}

	/**
	 * 步行 路线规划
	 * 
	 * @param fromPos
	 *            起点 坐标（经纬度）
	 * @param toPos
	 *            终点 坐标（经纬度）
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:25:01
	 * @update (date)
	 */
	public void startWalkingRoutePlan(LatLng fromPos, LatLng toPos,
			OnGetRoutePlanResultListener listener) {
		startWalkingRoutePlan(PlanNode.withLocation(fromPos),
				PlanNode.withLocation(toPos), listener);
	}

	/**
	 * 步行 路线规划
	 * 
	 * @param fromNode
	 *            起点
	 * @param toNode
	 *            终点
	 * @param listener
	 * @return void
	 * @autour BaoHong.Li
	 * @date 2015-8-12 下午4:51:32
	 * @update (date)
	 */
	public void startWalkingRoutePlan(PlanNode fromNode, PlanNode toNode,
			OnGetRoutePlanResultListener listener) {
		WalkingRoutePlanOption walkingRoutePlanOption = new WalkingRoutePlanOption();
		walkingRoutePlanOption.from(fromNode);
		walkingRoutePlanOption.to(toNode);
		startWalkingRoutePlan(walkingRoutePlanOption, listener);
	}

	public void startWalkingRoutePlan(WalkingRoutePlanOption option,
			OnGetRoutePlanResultListener listener) {
		if (null == mRoutePlanSearch) {
			mRoutePlanSearch = RoutePlanSearch.newInstance();
		}

		if (listener == null) {
			throw new IllegalArgumentException(
					"OnGetRoutePlanResultListener is null");
		}
		mOnGetRoutePlanResultListener = listener;
		mRoutePlanSearch
				.setOnGetRoutePlanResultListener(mOnGetRoutePlanResultListener);

		mRoutePlanSearch.walkingSearch(option);
	}

	/**
	 * 
	 * // 将google地图、soso地图、aliyun地图、mapabc地图和amap地图// 所用坐标转换成百度坐标 [ bd09ll -->
	 * gcj02]
	 * 
	 * @param sourceLatLng
	 * @return LatLng
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午4:53:28
	 * @update (date)
	 */
	public static LatLng convretGcj02Tobd09ll(double latitude, double longitude) {
		return convretGcj02Tobd09ll(new LatLng(latitude, longitude));
	}

	/**
	 * 
	 * // 将google地图、soso地图、aliyun地图、mapabc地图和amap地图// 所用坐标转换成百度坐标 <p>[ bd09ll -->
	 * gcj02]
	 * 
	 * @param sourceLatLng
	 * @return LatLng
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午4:53:28
	 * @update (date)
	 */
	public static LatLng convretGcj02Tobd09ll(LatLng sourceLatLng) {
		CoordinateConverter converter = new CoordinateConverter();
		converter
				.from(com.baidu.mapapi.utils.CoordinateConverter.CoordType.COMMON);
		// sourceLatLng待转换坐标
		converter.coord(sourceLatLng);
		return converter.convert();
	}
	

	/**
	 * 
	 * // 将GPS设备采集的原始GPS坐标转换成百度坐标
	 * 
	 * @param sourceLatLng
	 * @return LatLng
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午4:58:11
	 * @update (date)
	 */
	public static LatLng convretGPSToBd09ll(double latitude, double longitude) {
		return convretGPSToBd09ll(new LatLng(latitude,longitude));
	}
	
	/**
	 * 
	 * // 将GPS设备采集的原始GPS坐标转换成百度坐标
	 * 
	 * @param sourceLatLng
	 * @return LatLng
	 * @autour BaoHong.Li
	 * @date 2015-8-13 下午4:58:11
	 * @update (date)
	 */
	public static LatLng convretGPSToBd09ll(LatLng sourceLatLng) {
		CoordinateConverter converter = new CoordinateConverter();
		converter
				.from(com.baidu.mapapi.utils.CoordinateConverter.CoordType.GPS);
		// sourceLatLng待转换坐标
		converter.coord(sourceLatLng);
		return converter.convert();
	}

	
	/**
	 *
	 * 国测局坐标 （GCJ02）--> 百度<i>经纬度球面坐标</i>(BD09ll)
	* @param sourceLocation
	* @return BDLocation
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:27:18 
	* @update (date)
	 */
	public static BDLocation convretGcj02ToBd09ll(BDLocation sourceLocation){
		return LocationClient.getBDLocationInCoorType(sourceLocation, BDLocation.BDLOCATION_GCJ02_TO_BD09LL);
	}
	
	
	/**
	 * 百度 <i>经纬度球面坐标</i>(BD09ll) -->国测局坐标 （GCJ02）
	* @param sourceLatLng (经纬度)
	* @return BDLocation 
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:38:10 
	* @update (date)
	 */
	public static BDLocation convertBd09llToGcj02(LatLng sourceLatLng){
		BDLocation bdLocation = new BDLocation();
		bdLocation.setLatitude(sourceLatLng.latitude);
		bdLocation.setLongitude(sourceLatLng.longitude);
		return convertBd09llToGcj02(bdLocation);
	}
	
	
	/**
	 * 百度 <i>经纬度球面坐标</i>(BD09ll) -->国测局坐标 （GCJ02）
	* @param sourceLocation
	* @return BDLocation
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:28:44 
	* @update (date)
	 */
	public static BDLocation convertBd09llToGcj02(BDLocation sourceLocation){
		return LocationClient.getBDLocationInCoorType(sourceLocation, BDLocation.BDLOCATION_BD09LL_TO_GCJ02);
	}


	/**
	 *
	 *国测局坐标 （GCJ02）--> 百度 <i>墨卡托平面坐标</i>(BD09 /BD09_MC) 
	* @param sourceLatLng （国测局 经纬度）
	* @return BDLocation
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:30:35 
	* @update (date)
	 */
	public static BDLocation convertGcj02ToBd09(LatLng sourceLatLng){
		BDLocation bdLocation = new BDLocation();
		bdLocation.setLatitude(sourceLatLng.latitude);
		bdLocation.setLongitude(sourceLatLng.longitude);
		return convertGcj02ToBd09(bdLocation);
	}
	

	/**
	 *
	 *国测局坐标 （GCJ02）--> 百度 <i>墨卡托平面坐标</i>(BD09 /BD09_MC) 
	* @param sourceLocation
	* @return BDLocation
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:30:35 
	* @update (date)
	 */
	public static BDLocation convertGcj02ToBd09(BDLocation sourceLocation){
		return LocationClient.getBDLocationInCoorType(sourceLocation, BDLocation.BDLOCATION_GCJ02_TO_BD09);
	}

	/**
	 *
	 * 百度 <i>墨卡托平面坐标</i>(BD09 / BD09_MC) -->国测局坐标 （GCJ02）
	* @param sourceLocation
	* @return BDLocation
	* @autour BaoHong.Li
	* @date 2015-8-13 下午8:29:32 
	* @update (date)
	 */
	public static BDLocation convertBd09ToGcj02(BDLocation sourceLocation){
		return LocationClient.getBDLocationInCoorType(sourceLocation, BDLocation.BDLOCATION_BD09_TO_GCJ02);
	}
	
	
	/**
	 * 
	 * 初始化 百度导航 引擎 ，（在 首个activity 中）
	 * 
	 * @autour BaoHong.Li
	 * @date 2015-8-13 上午11:42:29
	 * @update (date)
	 */
//	public void initNavi(Activity activity, NaviInitListener naviInitListener,
//			BNOuterTTSPlayerCallback ttsCallback) {

//	}

}
